#pragma once

#include <QGraphicsScene>
#include <QMap>
#include <QPainterPath>

#include "LeGraphics.h"
#include "LeGraphicsPalette.h"
#include "LeGraphicsSceneEventFilter.h"

class LeGraphicsItem;
class LeGraphicsItemLayer;
class LeGraphicsStyle;

class LEGRAPHICSVIEW_EXPORT LeGraphicsScene : public QGraphicsScene
{
    Q_OBJECT

    Q_PROPERTY(LeGraphicsItemLayer* currentLayer READ currentLayer WRITE setCurrentLayer NOTIFY currentLayerChanged)

public:
    explicit LeGraphicsScene(QObject *parent = nullptr);

    // Layer management
public:
    QList<LeGraphicsItemLayer *> featureLayers() const;
    LeGraphicsItemLayer *currentLayer() const;
    LeGraphicsItemLayer *backgroundLayer() const;
    LeGraphicsItemLayer *foregroundLayer() const;

signals:
    void currentLayerChanged(LeGraphicsItemLayer *layer);
    void aboutToAddLayer();
    void layerAdded();
    void aboutToRemoveLayer();
    void layerRemoved();
    void aboutToChangeLayerOrdering();
    void layerOrderingChanged();

public slots:
    void clearLayers();
    void setLayers(const QList<LeGraphicsItemLayer *> &featureLayers);
    void changeLayerOrdering(const QList<LeGraphicsItemLayer *> &order);
    void setCurrentLayer(LeGraphicsItemLayer *layer);

    // Rendering
public slots:
    void setFeatureLayersOpacity(qreal opacity);
    void setGraphicsPalette(const LeGraphicsPalette &graphicsPalette);
    LeGraphicsPalette graphicsPalette() const;
    LeGraphicsStyle *graphicsStyle() const;

    // Event filtering
public:
    void setEventFilter(LeGraphicsSceneEventFilter *filter);

    // Behaviour
public slots:
    void enableToolTip(bool set = true);
public:
    bool toolTipEnabled() const;

    // Item selection
private:
    void updateSelection();

    // Purely informational for now:
public:
    qreal unitScaleFactor() const;
    QString unitOfMeasure() const;
public slots:
    void setUnitScaleFactor(qreal factor);
    void setUnitOfMeasure(const QString &unit);

public slots:
    void enableTransparentLayers(bool enabled);
    void enableDropShadowEffect(bool enabled);

private:
    Q_DISABLE_COPY(LeGraphicsScene)

    LeGraphicsPalette m_palette;
    LeGraphicsStyle *m_style;
    LeGraphicsItemLayer *m_backgroundLayer;
    LeGraphicsItemLayer *m_foregroundLayer;
    QList<LeGraphicsItemLayer *> m_layerList;
    LeGraphicsItemLayer *m_currentLayer;
    bool m_layerTransparencyEnabled;
    qreal m_layerOpacity;
    qreal m_unitScaleFactor;
    QString m_unitOfMeasure;
    bool m_toolTipEnabled;
    void updateLayerItemDrawingOrder();
    LeGraphicsSceneEventFilter *m_eventFilter = nullptr;

    // QGraphicsScene interface
protected:
    virtual void drawBackground(QPainter *painter, const QRectF &rect) override;
    virtual void drawForeground(QPainter *painter, const QRectF &rect) override;
    virtual void keyPressEvent(QKeyEvent *event) override;
    virtual void keyReleaseEvent(QKeyEvent *event) override;
    virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
    virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
    virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
    virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
};
